package com.hzit.portal.service.impl;

import com.hzit.portal.service.PortalService;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.api.RemoteManagerService;
import com.ruoyi.system.api.domain.Content;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Service
@Slf4j
public class PortalServiceImpl implements PortalService {

	@Autowired
	private RemoteManagerService managerService;
	@Autowired
	private RedisService redisService;
	/**
	 * 根据分类查询广告列表（远程调用）
	 * 一次性将集合数据全部放到redis中
	 * @param id
	 * @return
	 */
	@Override
	public List<Content> findContentsByCateId(Long id) {
		// 1.1 从redis中取得数据
		List<Content> cacheList = redisService.getCacheList(CacheConstants.CONTENT_LIST);
		// 1.2 如果有值就返回
		if(!CollectionUtils.isEmpty(cacheList)){
			return cacheList;
		}
		log.info("正在从数据库中取得数据。。。");
		// 1.3 从数据库取得广告数据
		R<List<Content>> r = managerService.findContentsByCateId(id);
		cacheList = r.getData();
		// 1.4 将数据保存到redis中
		redisService.setCacheList(CacheConstants.CONTENT_LIST,cacheList);

		return cacheList;
	}

	/**
	 * 以hash的方式存放数据
	 * @param id
	 * @return
	 */
	@Override
	public List<Content> findContentsByCateId2(long id) {
		// 1.1 从redis中取得数据
		Collection<Object> values = redisService.getCacheMap(CacheConstants.CONTENT_LIST).values();
		List<Content> collect = null;
		// 1.2 如果不为空就直接转换
		if(!CollectionUtils.isEmpty(values)){
			collect = values.stream().map(m -> (Content) m).collect(Collectors.toList());
		}else{
			// 1.3 从数据库取得广告数据
			log.info("正在从数据库中取得数据...");
			R<List<Content>> r = managerService.findContentsByCateId(id);
			collect = r.getData();
			// 1.4 将从数据库中取得的数据存到redis中
			for (Content content : collect) {
				redisService.setCacheMapValue(CacheConstants.CONTENT_LIST,content.getId() + "",content);
			}
		}
		return collect;
	}

	/**
	 * 解决数据一致性问题,使用SpringCache框架
	 * @param id
	 * @return
	 */
	@Override
	// 首先,查找在redis中以contentList::findContentsByCateId3为key是否有数据,有就返回,否则就查询数据库
	@Cacheable(cacheNames = "contentList",key = "#root.methodName")
	public List<Content> findContentsByCateId3(long id) {
		log.info("正在查询数据库3...");
		R<List<Content>> r = managerService.findContentsByCateId(id);
		List<Content> data = r.getData();
		return data;
	}


	// 一直会执行方法体
	@Override
	@CachePut(cacheNames = "findById",key = "#p0")
	public Content findById(Long id) {
		log.info("findById({})被调用",id);
		R<Content> r = managerService.findById(id);
		Content data = r.getData();
		return data;
	}

}
